package com.appistry.management.domain.impl;

import java.net.InetAddress;
import java.util.List;
import java.util.Map;

import org.json.JSONException;

import com.appistry.api.rest.domain.RestResponse;
import com.appistry.management.Service;
import com.appistry.management.ServiceApp;
import com.appistry.management.ServiceConfig;
import com.appistry.management.ServiceInfo;
import com.appistry.management.State;
import com.appistry.management.domain.AbstractRestDomainObject;
import com.appistry.management.domain.ControllerAction;
import com.appistry.management.exception.FabricManagerException;
import com.appistry.management.rest.RestFabricManager;
import com.appistry.management.util.JsonTransformUtil;

public class ServiceImpl extends AbstractRestDomainObject implements Service{
	private RestFabricManager restFabricManager;
	private String serviceName;

	public ServiceImpl(RestFabricManager restFabricManager, String serviceName) {
		this.restFabricManager = restFabricManager;
		this.serviceName = serviceName;
	}

	public String getName() {
		return serviceName;
	}

	public ServiceInfo getServiceInfo() throws FabricManagerException{
		try {
			RestResponse restResponse = restFabricManager.getServiceInfo(serviceName);
			checkForErrors(restResponse);

			ServiceInfo serviceInfo = JsonTransformUtil.toServiceInfo(restResponse.getBodyAsString());

			return serviceInfo;

		} catch (JSONException e) {
			throw new FabricManagerException(PARSE_JSON_ERR, e);
		} catch (Exception e) {
			throw new FabricManagerException(e);
		}
	}
	
	public void reboot() throws FabricManagerException {
		serviceController(serviceName,ControllerAction.REBOOT);	
	}

	public void start() throws FabricManagerException {
		serviceController(serviceName,ControllerAction.START);		
	}

	public void stop() throws FabricManagerException {
		serviceController(serviceName,ControllerAction.STOP);	
	}
	
	public boolean serviceController(String serviceName, ControllerAction action) throws FabricManagerException {
		try {
			RestResponse restResponse = restFabricManager.serviceController(serviceName, action);
			checkForErrors(restResponse);

			return true;
		} catch (Exception e) {
			throw new FabricManagerException(e);
		}
	}

	public List<ServiceApp> getServiceApps() throws FabricManagerException {
		try {
			RestResponse restResponse = restFabricManager.getServiceAppList(serviceName);
			checkForErrors(restResponse);

			List<ServiceApp> apps = JsonTransformUtil.toServiceAppList(restFabricManager, this, restResponse.getBodyAsString());
			
			return apps;
		} catch (JSONException e) {
			throw new FabricManagerException(PARSE_JSON_ERR, e);
		} catch (Exception e) {
			throw new FabricManagerException(e);
		}
	}

	public Map<InetAddress, State> getState() throws FabricManagerException {
		try {
			RestResponse restResponse = restFabricManager.getServiceState(serviceName);
			checkForErrors(restResponse);
			
			Map<InetAddress, State> workerStateMap = JsonTransformUtil.toWorkerStateMap(restResponse.getBodyAsString());
			
			return workerStateMap;
		} catch (JSONException e) {
			throw new FabricManagerException(PARSE_JSON_ERR, e);
		} catch (Exception e) {
			throw new FabricManagerException(e);
		}
	}

	public List<ServiceConfig> getServiceConfigs() throws FabricManagerException {
		try {
			RestResponse restResponse = restFabricManager.getServiceConfigList(serviceName);
			checkForErrors(restResponse);

			List<ServiceConfig> list = JsonTransformUtil.toServiceConfigList(restFabricManager, this, restResponse.getBodyAsString());

			return list;
		} catch (JSONException e) {
			throw new FabricManagerException(PARSE_JSON_ERR, e);
		} catch (Exception e) {
			throw new FabricManagerException(e);
		}
	}
}
